package chip;


/**
 * @author Mathieu Rousseau
 * @email mathieu.rousseau3@mail.mcgill.ca
 */


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;


/** ------------------------------------------------------------------------------------------------------------------
 * start of BackgroundRemover class
 * Version 1.0
 * January 26th, 2011
 * ------------------------------------------------------------------------------------------------------------------  */
public class BackgroundRemover {

	
	/*  global variables  */
	private static final String inputPath = "BackgroundRemover/Input/";
	private static final String outputPath = "BackgroundRemover/Output/";
	private static String numeratorFilename;
	private static String denominatorFilename;
	private static String experimentName = "default_name";
	private static int numberOfEntries = 0;
	private static String numeratorHeaderLines[];
	private static String denominatorHeaderLines[];
	private static String[] numeratorEntries;
	private static String[] denominatorEntries;
	/*  end of global variables  */
	
	
	/*  start of readFiles method  */
	private static void readFiles(){
		System.out.println("\tReading the input files...");
		
		
		//  find the size of the input files
		String line = null;
		int lineCounter = 0;
		try{
			BufferedReader br = new BufferedReader(new FileReader(inputPath + numeratorFilename));			
			while((line = br.readLine()) != null){
				lineCounter++;
			}
			br.close();
		}catch (IOException e) {
			e.printStackTrace();
			System.out.println("Error: cannot find regions file with filename \"" + numeratorFilename + "\"\n" +
			"System.exit(0)");
			System.exit(0);
		}
		//  Note: there are two (2) header lines
		numberOfEntries = lineCounter - 2;
		
		
		//  read the numerator file
		numeratorEntries = new String[numberOfEntries];
		numeratorHeaderLines = new String[2];
		line = null;
		lineCounter = 0;
		try{
			BufferedReader br = new BufferedReader(new FileReader(inputPath + numeratorFilename));			
			while((line = br.readLine()) != null){
				//  Note: there are two header lines
				if(lineCounter == 0){
					numeratorHeaderLines[0] = line;
				}
				else if(lineCounter == 1){
					numeratorHeaderLines[1] = line;
				}
				else{
					//  there are two (2) header lines that need to be skipped
					numeratorEntries[lineCounter-2] = line;
//					System.out.println(line);
				}
				lineCounter++;
			}
			br.close();
		}catch (IOException e) {
			e.printStackTrace();
			System.out.println("Error: cannot find regions file with filename \"" + numeratorFilename + "\"\n" +
			"System.exit(0)");
			System.exit(0);
		}
//		System.out.println("number of lines = " + lineCounter);
		System.out.println("\t\tOpened and read numerator file: " + numeratorFilename);
		
		
		//  read the denominator file
		denominatorEntries = new String[numberOfEntries];
		denominatorHeaderLines = new String[2];
		line = null;
		lineCounter = 0;
		try{
			BufferedReader br = new BufferedReader(new FileReader(inputPath + denominatorFilename));			
			while((line = br.readLine()) != null){
				//  Note: there are two header lines
				if(lineCounter == 0){
					denominatorHeaderLines[0] = line;
				}
				else if(lineCounter == 1){
					denominatorHeaderLines[1] = line;
				}
				else{
					//  there are two (2) header lines that need to be skipped
					denominatorEntries[lineCounter-2] = line;
//					System.out.println(line);
				}
				lineCounter++;
			}
			br.close();
		}catch (IOException e) {
			e.printStackTrace();
			System.out.println("Error: cannot find regions file with filename \"" + denominatorFilename + "\"\n" +
			"System.exit(0)");
			System.exit(0);
		}
//		System.out.println("number of lines = " + lineCounter);
		System.out.println("\t\tOpened and read denominator file: " + denominatorFilename);
	}/*  end of readFiles method  */
	
	
	/*  start of outputFiles method  */
	/*
	 *  Note: the header of the output files corresponds to the header of the numerator file
	 */
	private static void outputFiles(){
		
		String outputFilenameRatioOfLogs = experimentName + "_ratio_of_logs.bed";
		String outputFilenameLogOfRatio = experimentName + "_log_of_ratio.bed";
		
		try{						
			BufferedWriter bwRatioOfLogs = new BufferedWriter(new FileWriter(outputPath + outputFilenameRatioOfLogs));
			BufferedWriter bwLogOfRatio = new BufferedWriter(new FileWriter(outputPath + outputFilenameLogOfRatio));
			
			//  write the header lines
			bwRatioOfLogs.write(numeratorHeaderLines[0]);
			bwRatioOfLogs.newLine();
			bwRatioOfLogs.flush();
			bwRatioOfLogs.write(numeratorHeaderLines[1]);
			bwRatioOfLogs.newLine();
			bwRatioOfLogs.flush();
			
			bwLogOfRatio.write(numeratorHeaderLines[0]);
			bwLogOfRatio.newLine();
			bwLogOfRatio.flush();
			bwLogOfRatio.write(numeratorHeaderLines[1]);
			bwLogOfRatio.newLine();
			bwLogOfRatio.flush();
			
			
			
			//  calculate and write the entries to file
			for(int i=0; i<numberOfEntries; i++){
				
				String numeratorLineSplit[] = numeratorEntries[i].split("\t");
				String denominatorLineSplit[] = denominatorEntries[i].split("\t");
				
				double numeratorValue = Double.parseDouble(numeratorLineSplit[3]);
				double denominatorValue = Double.parseDouble(denominatorLineSplit[3]);
				
				String prefix = numeratorLineSplit[0] + "\t" + numeratorLineSplit[1] + "\t" + numeratorLineSplit[2] + "\t";
				
				
				double ratioOfLogsValue = 0;
				if(denominatorValue != 0){			//  make sure not to divide by zero
					ratioOfLogsValue = numeratorValue / denominatorValue;
				}
				else{
//					System.out.println("Caught attempt to divide by zero in calculating the ratio of logs.\n\tSetting ratio to zero (0) and continuing.");
				}
				if(ratioOfLogsValue < 0){
//					System.out.println("The ratio of logs value is smaller than zero.\n\tSetting ratio to zero (0) and continuing");
					ratioOfLogsValue = 0;
				}
				bwRatioOfLogs.write(prefix + ratioOfLogsValue);
				bwRatioOfLogs.newLine();
				bwRatioOfLogs.flush();
				
				
				//  the log of the ratio is the same thing as the difference of the log of the numerator and the log of the denominator
				//  i.e. log(x/y) = log(x) - log(y)
				double logOfRatiosValue = numeratorValue - denominatorValue;
				if(logOfRatiosValue < 0){
//					System.out.println("The log of ratio value is smaller than zero.\n\tSetting log to zero (0) and continuing");
					logOfRatiosValue = 0;
				}
				bwLogOfRatio.write(prefix + logOfRatiosValue);
				bwLogOfRatio.newLine();
				bwLogOfRatio.flush();
			}
			
			
			bwRatioOfLogs.close();
			bwLogOfRatio.close();
		}catch (IOException e) {
			e.printStackTrace();
		}//end of try-catch block
		System.out.println("\t\tOutput file: " + outputFilenameRatioOfLogs);
		System.out.println("\t\tOutput file: " + outputFilenameLogOfRatio);
	}/*  end of outputFiles method  */
	
	
	/*  start of main method  */
	public static void main(String[] args) {
		
		
		//  THP1 0Hr
		//  the plus strands
//		experimentName = "THP1_0h_K27_H3_hg18_+";
//		numeratorFilename = "log2Ratios_BEDGraph_binned_THP1_0h_K27_Red_THP1_0h_K27_Green_HOXA_hg18_+.bed";
//		denominatorFilename = "log2Ratios_BEDGraph_binned_THP1_0h_H3_Red_THP1_0h_H3_Green_HOXA_hg18_+.bed";
		
		//  the negative strands
//		experimentName = "THP1_0h_K27_H3_hg18_-";
//		numeratorFilename = "log2Ratios_BEDGraph_binned_THP1_0h_K27_Red_THP1_0h_K27_Green_HOXA_hg18_-.bed";
//		denominatorFilename = "log2Ratios_BEDGraph_binned_THP1_0h_H3_Red_THP1_0h_H3_Green_HOXA_hg18_-.bed";

		
		
		
		//  NT2 siCTCF
		//  the plus strands
//		experimentName = "NT2siCTCF_K27_H3_hg18_+";
//		numeratorFilename = "log2Ratios_BEDGraph_binned_NT2siCTCF_K27_Red_NT2siCTCF_K27_Green_HOXA_hg18_+.bed";
//		denominatorFilename = "log2Ratios_BEDGraph_binned_NT2siCTCF_H3_Red_NT2siCTCF_H3_Green_HOXA_hg18_+.bed";
		
		//  the negative strands
//		experimentName = "NT2siCTCF_K27_H3_hg18_-";
//		numeratorFilename = "log2Ratios_BEDGraph_binned_NT2siCTCF_K27_Red_NT2siCTCF_K27_Green_HOXA_hg18_-.bed";
//		denominatorFilename = "log2Ratios_BEDGraph_binned_NT2siCTCF_H3_Red_NT2siCTCF_H3_Green_HOXA_hg18_-.bed";
		
		
		
		
		//  NT2 siNC
		//  the plus strands
//		experimentName = "NT2siNC_K27_H3_hg18_+";
//		numeratorFilename = "log2Ratios_BEDGraph_binned_NT2siNC_K27_Red_NT2siNC_K27_Green_HOXA_hg18_+.bed";
//		denominatorFilename = "log2Ratios_BEDGraph_binned_NT2siNC_H3_Red_NT2siNC_H3_Green_HOXA_hg18_+.bed";
		
		//  the negative strands
//		experimentName = "NT2siNC_K27_H3_hg18_-";
//		numeratorFilename = "log2Ratios_BEDGraph_binned_NT2siNC_K27_Red_NT2siNC_K27_Green_HOXA_hg18_-.bed";
//		denominatorFilename = "log2Ratios_BEDGraph_binned_NT2siNC_H3_Red_NT2siNC_H3_Green_HOXA_hg18_-.bed";

		
		
		System.out.println("Experiment Name: \t" + experimentName);
		
		readFiles();
		
		outputFiles();
		
		System.out.println("\tDone!");
		
	}/*  end of main method  */

}
